package com.studyweb.controller;

import com.studyweb.pojo.entity.FileUpload;
import com.studyweb.pojo.vo.Result;
import com.studyweb.service.FileUploadService;
import com.studyweb.utils.JwtUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件上传控制器
 * 
 * @author StudyWeb Team
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/upload")
@Validated
@Tag(name = "文件上传管理", description = "文件上传、下载、删除等相关接口")
public class FileUploadController {
    
    @Autowired
    private FileUploadService fileUploadService;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    /**
     * 上传文件接口
     * 
     * @param file 上传的文件
     * @param module 所属模块（可选）
     * @param request HTTP请求对象，用于获取JWT token
     * @return Result 上传结果
     */
    @Operation(summary = "上传文件", description = "上传单个文件到服务器")
    @PostMapping("/file")
    public Result uploadFile(
            @Parameter(description = "要上传的文件", required = true) 
            @RequestParam("file") MultipartFile file,
            @Parameter(description = "所属模块", required = false) 
            @RequestParam(value = "module", required = false) String module,
            HttpServletRequest request) {
        try {
            // 检查文件是否为空
            if (file == null || file.isEmpty()) {
                return Result.error("请选择要上传的文件");
            }
            
            // 获取当前用户ID
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 上传文件
            Map<String, Object> result = ((com.studyweb.service.impl.FileUploadServiceImpl) fileUploadService).uploadFile(file, userId, module);
            
            log.info("文件上传成功，用户ID：{}, 文件名：{}", userId, file.getOriginalFilename());
            return Result.success("文件上传成功", result);
            
        } catch (IllegalArgumentException e) {
            log.warn("文件上传参数错误：{}", e.getMessage());
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("文件上传异常：{}", e.getMessage(), e);
            return Result.error("文件上传失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取文件信息接口
     * 
     * @param fileId 文件ID
     * @param request HTTP请求对象
     * @return Result 文件信息
     */
    @GetMapping("/file/{fileId}")
    public Result getFileInfo(@PathVariable Long fileId, HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 获取文件信息
            FileUpload fileUpload = fileUploadService.getFileById(fileId);
            if (fileUpload == null) {
                return Result.error("文件不存在");
            }
            
            // 检查权限（只能查看自己上传的文件）
            if (!fileUpload.getUserId().equals(userId)) {
                return Result.error("无权限访问该文件");
            }
            
            return Result.success("获取文件信息成功", fileUpload);
            
        } catch (Exception e) {
            log.error("获取文件信息异常：{}", e.getMessage(), e);
            return Result.error("获取文件信息失败");
        }
    }
    
    /**
     * 获取用户文件列表接口
     * 
     * @param module 模块（可选）
     * @param request HTTP请求对象
     * @return Result 文件列表
     */
    @GetMapping("/list")
    public Result getUserFiles(
            @RequestParam(value = "module", required = false) String module,
            HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 获取用户文件列表
            List<FileUpload> files;
            if (module != null && !module.isEmpty()) {
                files = fileUploadService.getFilesByCondition(userId, null, 1, module);
            } else {
                files = fileUploadService.getFilesByUserId(userId);
            }
            
            return Result.success("获取文件列表成功", files);
            
        } catch (Exception e) {
            log.error("获取文件列表异常：{}", e.getMessage(), e);
            return Result.error("获取文件列表失败");
        }
    }
    
    /**
     * 删除文件接口
     * 
     * @param fileId 文件ID
     * @param request HTTP请求对象
     * @return Result 删除结果
     */
    @DeleteMapping("/file/{fileId}")
    public Result deleteFile(@PathVariable Long fileId, HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 删除文件
            boolean success = fileUploadService.deleteFile(fileId, userId);
            
            if (success) {
                return Result.success("文件删除成功");
            } else {
                return Result.error("文件删除失败");
            }
            
        } catch (Exception e) {
            log.error("删除文件异常：{}", e.getMessage(), e);
            return Result.error("删除文件失败");
        }
    }
    
    /**
     * 批量删除文件接口
     * 
     * @param fileIds 文件ID列表
     * @param request HTTP请求对象
     * @return Result 删除结果
     */
    @DeleteMapping("/batch")
    public Result batchDeleteFiles(@RequestBody List<Long> fileIds, HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 批量删除文件
            int successCount = fileUploadService.batchDeleteFiles(fileIds, userId);
            
            return Result.success("批量删除成功，成功删除 " + successCount + " 个文件");
            
        } catch (Exception e) {
            log.error("批量删除文件异常：{}", e.getMessage(), e);
            return Result.error("批量删除文件失败");
        }
    }
    
    /**
     * 获取文件内容接口
     * 
     * @param fileId 文件ID
     * @param request HTTP请求对象
     * @return 文件内容的字节流
     */
    @GetMapping("/content/{fileId}")
    public ResponseEntity<byte[]> getFileContent(@PathVariable("fileId") Long fileId, HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
            }
            
            // 获取文件信息
            FileUpload fileUpload = fileUploadService.getFileById(fileId);
            if (fileUpload == null) {
                return ResponseEntity.notFound().build();
            }
            
            // 检查权限（只能访问自己上传的文件）
            if (!fileUpload.getUserId().equals(userId)) {
                return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
            }
            
            // 获取文件内容
            byte[] fileContent = fileUploadService.getFileContent(fileId);
            if (fileContent == null) {
                return ResponseEntity.notFound().build();
            }
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            
            // 处理中文文件名编码问题
            String originalName = fileUpload.getOriginalName();
            try {
                // 使用UTF-8编码文件名
                String encodedFilename = java.net.URLEncoder.encode(originalName, "UTF-8").replaceAll("\\+", "%20");
                headers.add("Content-Disposition", "inline; filename*=UTF-8''" + encodedFilename);
            } catch (Exception e) {
                // 如果编码失败，使用简单的文件名
                headers.add("Content-Disposition", "inline; filename=\"file\"");
            }
            
            // CORS headers are handled by global CORS configuration
            headers.add("Access-Control-Expose-Headers", "Content-Disposition");
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(fileContent);
            
        } catch (Exception e) {
            log.error("获取文件内容异常：{}", e.getMessage(), e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    /**
     * 获取用户文件统计信息接口
     * 
     * @param request HTTP请求对象
     * @return Result 统计信息
     */
    @GetMapping("/stats")
    public Result getUserFileStats(HttpServletRequest request) {
        try {
            // 验证用户登录
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 获取统计信息
            Map<String, Object> stats = fileUploadService.getUserFileStats(userId);
            
            return Result.success("获取统计信息成功", stats);
            
        } catch (Exception e) {
            log.error("获取统计信息异常：{}", e.getMessage(), e);
            return Result.error("获取统计信息失败");
        }
    }
    
    /**
     * 批量上传文件接口
     * 
     * @param files 上传的文件数组
     * @param request HTTP请求对象
     * @return Result 上传结果
     */
    @PostMapping("/files")
    public Result uploadFiles(@RequestParam("files") MultipartFile[] files, HttpServletRequest request) {
        try {
            // 检查文件是否为空
            if (files == null || files.length == 0) {
                return Result.error("请选择要上传的文件");
            }
            
            // 获取当前用户ID
            String token = jwtUtils.getTokenFromRequest(request);
            if (!StringUtils.hasText(token)) {
                return Result.error("请先登录");
            }
            
            Long userId = jwtUtils.getUserIdFromToken(token);
            if (userId == null) {
                return Result.error("用户信息无效");
            }
            
            // 批量上传文件
            List<Map<String, Object>> results = new ArrayList<>();
            List<String> errors = new ArrayList<>();
            
            for (MultipartFile file : files) {
                try {
                    if (!file.isEmpty()) {
                        Map<String, Object> result = fileUploadService.uploadFile(file, userId);
                        results.add(result);
                    }
                } catch (Exception e) {
                    errors.add(file.getOriginalFilename() + ": " + e.getMessage());
                }
            }
            
            Map<String, Object> response = new HashMap<>();
            response.put("successCount", results.size());
            response.put("errorCount", errors.size());
            response.put("results", results);
            response.put("errors", errors);
            
            if (errors.isEmpty()) {
                log.info("批量文件上传成功，用户ID：{}, 成功数量：{}", userId, results.size());
                return Result.success("批量文件上传成功", response);
            } else {
                log.warn("批量文件上传部分失败，用户ID：{}, 成功数量：{}, 失败数量：{}", userId, results.size(), errors.size());
                return Result.success("批量文件上传完成，部分文件上传失败", response);
            }
            
        } catch (Exception e) {
            log.error("批量文件上传异常：{}", e.getMessage(), e);
            return Result.error("批量文件上传失败：" + e.getMessage());
        }
    }
}